
import colorama
import logging
import re
import sys
from mgamedev.py_lib.decorator import singleton     # noqa


def remove_ansi(s):
    ansi_escape = re.compile(r'(\x9B|\x1B\[)[0-?]*[ -\/]*[@-~]')
    return ansi_escape.sub('', s)


class ColorizingStreamHandler(logging.StreamHandler):
    color_map = {
        logging.DEBUG: colorama.Style.DIM + colorama.Fore.CYAN,
        logging.WARNING: colorama.Fore.YELLOW,
        logging.ERROR: colorama.Fore.RED,
        logging.CRITICAL: colorama.Back.RED,
    }

    def __init__(self, stream, color_map=None):
        logging.StreamHandler.__init__(self,
                                       colorama.AnsiToWin32(stream).stream)
        if color_map is not None:
            self.color_map = color_map

    @property
    def is_tty(self):
        isatty = getattr(self.stream, 'isatty', None)
        return isatty and isatty()

    def format(self, record):
        message = logging.StreamHandler.format(self, record)
        if self.is_tty:
            # Don't colorize a traceback
            parts = message.split('\n', 1)
            parts[0] = self.colorize(parts[0], record)
            message = '\n'.join(parts)
        else:
            message = remove_ansi(message)
        return message

    def colorize(self, message, record):
        try:
            return (self.color_map[record.levelno] + message +
                    colorama.Style.RESET_ALL)
        except KeyError:
            return message


@singleton
class Log(object):
    def __init__(self, name=__name__, path='mylog.log', level='DEBUG'):
        self.__name = name
        self.__path = path
        self.__level = level
        self.__logger = logging.getLogger(self.__name)
        self.__logger.setLevel(self.__level)

        stream_handler = self.__ini_handler()
        self.__set_handler(stream_handler)
        self.__set_formatter(stream_handler)
        self.__close_handler(stream_handler)

    def __ini_handler(self):
        """初始化handler"""
        stream_handler = ColorizingStreamHandler(sys.stdout)
        return stream_handler

    def __set_handler(self, stream_handler, level='DEBUG'):
        """设置handler级别并添加到logger收集器"""
        stream_handler.setLevel(level)

        self.__logger.addHandler(stream_handler)

    def __set_formatter(self, stream_handler):
        """设置日志输出格式"""
        strm_formater = logging.Formatter('%(message)s')
        stream_handler.setFormatter(strm_formater)

    def __close_handler(self, stream_handler):
        """关闭handler"""
        stream_handler.close()

    def logger(self):
        return self.__logger

    # 为不同的日志级别设置输出方法
    def debug(self, msg, *args):
        self.__logger.debug(msg, *args)

    def info(self, msg, *args):
        self.__logger.info(msg, *args)

    def warring(self, msg, *args):
        self.__logger.warning(msg, *args)

    def error(self, msg, *args):
        self.__logger.error(msg, *args)

    def critical(self, msg, *args):
        self.__logger.critical(msg, *args)


__all__ = [
    "Log"
]
